﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Artemis;

namespace JAWWS
{
    abstract class Actor : SceneGraphNode
    {
        protected float[] Position;
        protected int Health;
        protected Boolean Alive;
        protected PlayerLogic logic;
        protected int Strength;
        protected int Accuracy;
        protected float Speed;
        protected Random rand;
        protected Camera camera;
        protected MainForm main;
        protected float dx, dz;
        
        protected DateTime nextFrameTime;
        protected int currentFrame;
        protected int nextFrame;
        protected float[] modelScale;
        protected float frameDelay;
        protected int modelID;
        protected float frameFraction;
        
        public Actor()
        {
            Position = new float[3];
            logic = new PlayerLogic();
            rand = new Random();
            camera = new Camera();
            //----------------------------
            modelScale = new float[2];
            //----------------------------
            dx = 0.0f;
            dz = 0.0f;
        }        
        /*
         * Will allow an actor(Player/Enemy) to attack one another.
         * Params: Actor actor
         * Returns: Void
         */
        public abstract void attack(Actor actor);
        /*
         * An attack with an projectile
         * Params: Actor actor, Projectile proj
         * Returns: Void
         */
        public abstract void attack(Actor actor, Projectile proj);        
        /*
         * Move in a desiginated direction by dx/dz
         * Params: Int direction, float speed
         * Returns: Void
         */
        public void movePosition(int direction, float stepSpeed)
        {
            double angle = 0.0;
            // Forward (don't change dx,dz)
            if (direction == 0)
            {
                angle = 0.0;
            }
            // Front left 
            else if (direction == 1)
            {
                angle = Math.PI/4.0;
            }
            // Front Right
            else if (direction == 2)
            {
                angle = -(Math.PI / 4.0);
            }
            // Right Turn
            else if (direction == 3)
            {
                angle = -(Math.PI / 2.0);
            }
            // Left Turn
            else if (direction == 4)
            {
                angle = Math.PI / 2.0;
            }
            // Back Right
            else if (direction == 5)
            {
                angle = ((3.0 * Math.PI) / 2.0);
            }
            // Back Left
            else if (direction == 6)
            {
                angle = -((3.0 * Math.PI) / 2.0);
            }
            // Backwards
            else if (direction == 7)
            {
                angle = Math.PI;
            }

            // Rotate dx,dz
            float dx = getDx();
            float dz = getDz();
            setDx((float)Math.Cos(angle) * dx - (float)Math.Sin(angle) * dz);
            setDz((float)Math.Sin(angle) * dx + (float)Math.Cos(angle) * dz);
            //Moves Actor
            Position.SetValue((float)Position.GetValue(0) + stepSpeed * getDx(), 0);
            Position.SetValue((float)Position.GetValue(2) + stepSpeed * getDz(), 2);
        }
        /*
         * Draws the Actor
         * Params: Void
         * Returns: Void
         */
        public override abstract void draw();
        //Getter/Setter methods   
        /*
         * Adjusts the Actors health when either dammaged or raised.
         * Params: int Adjustment
         * Returns: Void
         */
        public void adjustHealth(int adjustment)
        {
            this.Health += adjustment;
        }
        /*
         * Sets the Health to a specific int
         * Params: int Health
         * Returns: void
         */
        public void setHealth(int health)
        {
            this.Health = health;
        }
        public void setDx(float change)
        {
            dx = change;
        }
        public float getDx()
        {
            return dx;
        }
        public void setDz(float change)
        {
            dz = change;
        }
        public float getDz()
        {
            return dz;
        }
        public float[] getPosition()
        {
            return Position;
        }
        public void setPosition(int index, float movementAmount)
        {
            Position.SetValue(movementAmount, index);
        }
       
        public int getHealth()
        {
            return Health;
        }
        public void setStr(int incrementAmmount)
        {
            this.Strength += incrementAmmount;
        }
        public void setAcc(int incremenetAmmount)
        {
            this.Accuracy += incremenetAmmount;
        }
        public void setSpeed(float incrementAmmount)
        {
            this.Speed += incrementAmmount;
        }
        public int getStr()
        {
            return Strength;
        }
        public int getAcc()
        {
            return Accuracy;
        }
        public float getSpeed()
        {
            return Speed;
        }
        public void setAlive(bool alive)
        {
            this.Alive = alive;
        }
        public bool getAlive()
        {
            return Alive;
        }
        public Camera getCamera()
        {
            return camera;
        }
        public void setModelID(int i)
        {
            modelID = i;
        }
        public int getModelID()
        {
            return modelID;
        }
        public int getCurrentFrame()
        {
            return currentFrame;
        }

        public int getNextFrame()
        {
            return nextFrame;
        }
    }
}
